﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using WSManager.Model;

namespace WSManager.Wpf
{
    public class CategoryViewModel: ViewModelBase<Category>
    {


        public bool CheckReferenced { get; set; }

        public Category Category
        {
            get

            {
                return Item;
            }
            set
            {
                Item = value;
            }
        }

        private ObservableCollection<CategoryViewModel> _subcategories;

        public ObservableCollection<CategoryViewModel> Subcategories
        {
            get
            {
                if (_subcategories == null)
                {
                    Subcategories = new ObservableCollection<CategoryViewModel>(Item.Subcategories.Select(s => new CategoryViewModel(s) { CheckReferenced = this.CheckReferenced }));

                    Subcategories.CollectionChanged += Subcategories_CollectionChanged;
                }
                return _subcategories;
            }
            set
            {
                _subcategories = value;
                foreach (var item in _subcategories)
                {
                    item.PropertyChanged += subcategory_PropertyChanged;
                }
                RaisePropertyChanged("Subcategories");
            }
        }

        void Subcategories_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
                foreach (var item in e.NewItems)
                {
                    Item.Subcategories.Add((item as CategoryViewModel).Category);
                }
            if (e.OldItems != null)
                foreach (var item in e.OldItems)
                {
                    Item.Subcategories.Remove((item as CategoryViewModel).Category);
                }
        }

        void subcategory_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Checked")
            {
                RefreshChecked();
            }
        }

        private void RefreshChecked()
        {
            if (CheckReferenced)
            {
                bool oneChecked = false;
                bool oneUnchecked = false;
                foreach (var item in _subcategories)
                {
                    if (item.Checked == true)
                        oneChecked = true;
                    else
                    {
                        if (item.Checked == null)
                            oneChecked = true;
                        oneUnchecked = true;
                    }
                }
                if (oneChecked && oneUnchecked)
                    Checked = null;
                else if (oneUnchecked)
                    Checked = false;
            }
        }

        public void RemoveSelectedSubcategories()
        {
            foreach (var item in _subcategories.ToList())
            {
                if (item.Checked == true)
                {
                    _subcategories.Remove(item);
                }
                else
                {
                    item.RemoveSelectedSubcategories();
                }
            }
        }

        private bool? _checked = false;

        public bool? Checked
        {
            get { return _checked; }
            set
            {
                _checked = value;
                if (value == true && CheckReferenced)
                    foreach (var item in _subcategories)
                    {
                        item.Checked = true;
                    }
                RaisePropertyChanged("Checked");
            }
        }


        public string Name
        {
            get { return Item.Name; }
            set
            {
                Item.Name = value;
                RaisePropertyChanged("Name");
            }
        }


        public string Description
        {
            get { return Item.Description; }
            set
            {
                Item.Description = value;
                RaisePropertyChanged("Description");
            }
        }

        public CategoryViewModel(Category category)
        {
            this.CheckReferenced = true;
            this.Category = category;
        }

        public static implicit operator Category(CategoryViewModel c)
        {
            if (c == null)
                return null;
            return c.Category;
        }
    }
}
